package main

import (
	"encoding/binary"
	"encoding/json"
	"fmt"
	"io"
	"net"
	"reflect"
	"time"
)

type Hello struct {
	Name string
	Uid  int
}

type LoginMsg struct {
	Account  string
	Password string
}

type UidMsg struct {
	Uid int
}

func addheader(data []byte) []byte {
	msg := make([]byte, 4+len(data))
	binary.BigEndian.PutUint32(msg, uint32(len(data)))
	copy(msg[4:], data)
	return msg
}

func sendmsg(conn net.Conn, lmsg interface{}) {
	msgType := reflect.TypeOf(lmsg)
	msgId := msgType.Elem().Name()

	m := map[string]interface{}{msgId: lmsg}

	//fmt.Println(m)

	data, err := json.Marshal(m)
	if err != nil {
		panic(err)
	}

	msg := addheader(data)
	//println(string(msg))

	conn.Write(msg)
}

func main() {
	conn, err := net.Dial("tcp", "127.0.0.1:8080")
	if err != nil {
		panic(err)
	}

	//restart:
	var user, passwd string
	fmt.Printf("user: ")
	fmt.Scanf("%s", &user)
	fmt.Printf("password: ")
	fmt.Scanf("%s", &passwd)

	lmsg := LoginMsg{
		Account:  user,
		Password: passwd,
	}

	sendmsg(conn, &lmsg)

	var datalen [4]byte
	msglenbuf := datalen[:4]

	if _, err := io.ReadFull(conn, msglenbuf); err != nil { //err写在判断条件内判断语句结束则销毁
		fmt.Println(err)
	}
	msglen := binary.BigEndian.Uint32(msglenbuf)

	msgdata := make([]byte, msglen)
	if _, err := io.ReadFull(conn, msgdata); err != nil {
		fmt.Println(err)
	}

	//fmt.Println(string(msgdata))

	var m map[string]json.RawMessage
	err = json.Unmarshal(msgdata, &m)
	if err != nil {
		panic(err)
	}
	retmsg := new(UidMsg)

	json.Unmarshal(m["UidMsg"], retmsg)

	//fmt.Println(retmsg)
	if retmsg.Uid == -1 {
		fmt.Println("user and password is not match")
		//goto restart
	} else {
		fmt.Println("login")
	}

	uid := retmsg.Uid

	hmsg := Hello{
		Name: "Server",
		Uid:  uid,
	}

	sendmsg(conn, &hmsg)

	time.Sleep(time.Second)

	conn.Close()
}
